﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace GrayParrot.Web.Formly
{
    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    public class TemplateOptions
    {
        /// <summary>
        /// Gets or sets the type of the data inside the input element...
        /// </summary>
        /// <value>
        /// The type.
        /// </value>
        [JsonProperty(PropertyName = "type", DefaultValueHandling=DefaultValueHandling.Ignore)]
        public string Type { get; internal set; }

        /// <summary>
        /// Used to add an html label to each field
        /// </summary>
        /// <value>
        /// The label.
        /// </value>
        [JsonProperty(PropertyName = "label")]
        public string Label { get; internal set; }

        /// <summary>
        /// Used to add the required attribute to a form field.
        /// </summary>
        /// <value>
        ///   <c>true</c> if required; otherwise, <c>false</c>.
        /// </value>
        [JsonProperty(PropertyName = "required")]
        public bool Required { get; internal set; }

        /// <summary>
        /// used to add the disabled attribute to a form field.
        /// </summary>
        /// <value>
        ///   <c>true</c> if disabled; otherwise, <c>false</c>.
        /// </value>
        [JsonProperty(PropertyName = "disabled", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool Disabled { get; internal set; }

        /// <summary>
        /// Used to add placeholder text to some inputs.
        /// </summary>
        /// <value>
        /// The Placeholder.
        /// </value>
        [JsonProperty(PropertyName = "placeholder")]
        public string Placeholder { get; internal set; }

        /// <summary>
        /// Used to add descriptive text to all inputs.
        /// </summary>
        /// <value>
        /// The description.
        /// </value>
        [JsonProperty(PropertyName = "description")]
        public string Description { get; internal set; }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="TemplateOptionsAttribute"/> is hidden.
        /// </summary>
        /// <value>
        ///   <c>true</c> if hidden; otherwise, <c>false</c>.
        /// </value>
        /// <remarks>
        /// Indicates that the field is statically declared as hidden.
        /// It is used when you known that the field is not to be shown
        /// </remarks>
        [JsonProperty(PropertyName = "hide", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool Hide { get; set; }

        /// <summary>
        /// Gets or sets the disable callback.
        /// </summary>
        /// <value>
        /// The disable callback.
        /// </value>
        /// <remarks>
        /// Used to declare a client function that return TRUE if the field is disable.
        /// This callback is used to dinamically enable or disable the field, on the value returned by the callback
        /// </remarks>
        [JsonProperty(PropertyName = "disableCallback", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public object DisableCallback { get; set; }

        /// <summary>
        /// Gets or sets the hidden callback.
        /// </summary>
        /// <value>
        /// The hidden callback.
        /// </value>
        /// <remarks>
        /// Used to declare a client function that return TRUE if the field is to be shown.
        /// This callback is used to dinamically hide or shown the field, on the value returned by the callback
        /// </remarks>
        [JsonProperty(PropertyName = "hideCallback", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string HideCallback { get; set; }

        /// <summary>
        /// Gets or sets the addon left.
        /// </summary>
        /// <value>
        /// The addon left.
        /// </value>
        [JsonProperty(PropertyName = "addonLeft",DefaultValueHandling=DefaultValueHandling.Ignore)]
        public AddOn AddonLeft { get; internal set; }

        /// <summary>
        /// Gets or sets the addon right.
        /// </summary>
        /// <value>
        /// The addon right.
        /// </value>
        [JsonProperty(PropertyName = "addonRight",DefaultValueHandling=DefaultValueHandling.Ignore)]
        public AddOn AddonRight { get; internal set; }

        /// <summary>
        /// Gets or sets the rows of a TextArea...
        /// </summary>
        /// <value>
        /// The rows.
        /// </value>
        [JsonProperty(PropertyName = "rows", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public Int16 Rows { get; internal set; }

        /// <summary>
        /// Gets or sets the cols of a TextArea...
        /// </summary>
        /// <value>
        /// The cols.
        /// </value>
        [JsonProperty(PropertyName = "cols", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public Int16 Cols { get; internal set; }

        /// <summary>
        /// Gets or sets the minimum.
        /// </summary>
        /// <value>
        /// The minimum.
        /// </value>
        [JsonProperty(PropertyName = "min", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public int Min { get; internal set; }

        /// <summary>
        /// Gets or sets the maximum.
        /// </summary>
        /// <value>
        /// The maximum.
        /// </value>
        [JsonProperty(PropertyName = "max", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public int Max { get; internal set; }

        /// <summary>
        /// Gets the minimum length...
        /// </summary>
        /// <value>
        /// The minimum length.
        /// </value>
        [JsonProperty(PropertyName = "minlength", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public int MinLength { get; internal set; }

        /// <summary>
        /// Gets or sets the maximum length...
        /// </summary>
        /// <value>
        /// The maximum.
        /// </value>
        [JsonProperty(PropertyName = "maxlength", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public int MaxLength { get; internal set; }

        /// <summary>
        /// Gets or sets the step.
        /// </summary>
        /// <value>
        /// The step.
        /// </value>
        [JsonProperty(PropertyName = "step", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public double Step { get; set; }

        /// <summary>
        /// Gets or sets the value.
        /// </summary>
        /// <value>
        /// The value.
        /// </value>
        [JsonProperty(PropertyName = "value", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public double? Value { get; set; }

        #region Repeating Section propoerties ( Array, List )
        /// <summary>
        /// Gets or sets the name of the repeat section.
        /// </summary>
        /// <value>
        /// The name of the repeat section.
        /// </value>
        [JsonProperty(PropertyName = "repeatSectionName", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string RepeatSectionName { get; set; }

        /// <summary>
        /// Gets or sets the fields for inner type of property like array or list<T>...
        /// </summary>
        /// <value>
        /// The fields.
        /// </value>
        [JsonProperty(PropertyName = "rsFields", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public List<RepeatSectionFieldItem> RSFields { get; set; }
        #endregion

        [JsonProperty(PropertyName = "fields", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public List<FieldItem> Fields { get; set; }

        /// <summary>
        /// Gets or sets the datepicker popup.
        /// </summary>
        /// <value>
        /// The datepicker popup.
        /// </value>
        [JsonProperty(PropertyName = "datepickerPopup", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string DatepickerPopup { get; set; }

        /// <summary>
        /// Gets or sets the callback.
        /// </summary>
        /// <value>
        /// The callback.
        /// </value>
        [JsonProperty(PropertyName = "callback", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Callback { get; set; }

        /// <summary>
        /// Gets or sets the group property.
        /// </summary>
        /// <value>
        /// The group property.
        /// </value>
        [JsonProperty(PropertyName = "groupProp", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string GroupProp { get; set; }

        /// <summary>
        /// Gets or sets the options.
        /// </summary>
        /// <value>
        /// The options.
        /// </value>
        [JsonProperty(PropertyName = "options", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public List<object> Options { get; set; }

        /// <summary>
        /// Gets or sets the label property.
        /// </summary>
        /// <value>
        /// The label property.
        /// </value>
        [JsonProperty(PropertyName = "labelProp", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string LabelProp { get; set; }

        /// <summary>
        /// Gets or sets the value property.
        /// </summary>
        /// <value>
        /// The value property.
        /// </value>
        [JsonProperty(PropertyName = "valueProp", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string ValueProp { get; set; }

        /// <summary>
        /// Gets or sets the mask.
        /// </summary>
        /// <value>
        /// The mask.
        /// </value>
        [JsonProperty(PropertyName = "mask", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Mask { get; set; }

        /// <summary>
        /// Gets or sets the data datetimepicker configuration.
        /// </summary>
        /// <value>
        /// The data datetimepicker configuration.
        /// </value>
        [JsonProperty(PropertyName = "dataDatetimepickerConfig", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public DataDatetimepickerConfig DataDatetimepickerConfig { get; set; }

        /// <summary>
        /// Gets or sets the depends by.
        /// </summary>
        /// <value>
        /// The depends by.
        /// </value>
        [JsonProperty(PropertyName = "dependsBy", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string DependsBy { get; set; }

        /// <summary>
        /// Gets or sets the default value.
        /// </summary>
        /// <value>
        /// The default value.
        /// </value>
        [JsonProperty(PropertyName = "defaultValue", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public object DefaultValue { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [force load].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [force load]; otherwise, <c>false</c>.
        /// </value>
        [JsonProperty(PropertyName = "forceLoad", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool ForceLoad { get; set; }

        /// <summary>
        /// Gets or sets the options attribute.
        /// </summary>
        /// <value>
        /// The options attribute.
        /// </value>
        [JsonProperty(PropertyName = "optionsAttr", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string OptionsAttr { get; set; }

        /// <summary>
        /// Gets the ng options.
        /// </summary>
        /// <value>
        /// The ng options.
        /// </value>
        [JsonProperty(PropertyName = "ngOptions", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string NgOptions { get; internal set; }

        /// <summary>
        /// Gets or sets the refresh delay.
        /// </summary>
        /// <value>
        /// The refresh delay.
        /// </value>
        [JsonProperty(PropertyName = "refreshDelay", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public int RefreshDelay { get; set; }

        /// <summary>
        /// Gets or sets the refresh.
        /// </summary>
        /// <value>
        /// The refresh.
        /// </value>
        [JsonProperty(PropertyName = "refresh", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public object Refresh { get; set; }

        /// <summary>
        /// Gets or sets the refresh.
        /// </summary>
        /// <value>
        /// The refresh.
        /// </value>
        [JsonProperty(PropertyName = "minimumInputLength", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public uint MinimumInputLength { get; set; }

        /// <summary>
        /// Gets or sets the refresh.
        /// </summary>
        /// <value>
        /// The refresh.
        /// </value>
        [JsonProperty(PropertyName = "info", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Info { get; set; }

        /// <summary>
        /// Gets or sets the edit callback.
        /// </summary>
        /// <value>
        /// The edit callback.
        /// </value>
        [JsonProperty(PropertyName = "editProp", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string EditProp { get; set; }

        /// <summary>
        /// Gets or sets the field group.
        /// </summary>
        /// <value>
        /// The field group.
        /// </value>
        [JsonProperty(PropertyName = "fieldGroup", DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling=NullValueHandling.Ignore)]
        public FieldGroupDetail FieldGroup { get; set; }

        /// <summary>
        /// Gets or sets the draw direction.
        /// </summary>
        /// <value>
        /// The draw direction.
        /// </value>
        [JsonProperty(PropertyName = "drawDirection", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public DrawDirections DrawDirection { get; set; }

        /// <summary>
        /// Gets or sets the folder image path...
        /// </summary>
        /// <value>
        /// The folder.
        /// </value>
        [JsonProperty(PropertyName = "folder", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Folder { get; set; }

        [JsonIgnore()]
        public List<EventCallback> Events { get; set; }

        /* GrayParrotDateTimePickerOptionsAttribute */
        [JsonProperty(PropertyName = "format", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Format { get; set; }
        [JsonProperty(PropertyName = "initDate", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public DateTime? InitialDate { get; set; }
        [JsonProperty(PropertyName = "showMeridian", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool ShowMeridian { get; set; }
        [JsonProperty(PropertyName = "autoclose", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool Autoclose { get; set; }
        [JsonProperty(PropertyName = "todayBtn", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool TodayButton { get; set; }
        [JsonProperty(PropertyName = "todayHighlight", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool TodayHighlight { get; set; }
        [JsonProperty(PropertyName = "language", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string Language { get; set; }
        [JsonProperty(PropertyName = "minuteStep", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public short MinuteStep { get; set; }
        [JsonProperty(PropertyName = "minView", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public short MinView { get; set; }
        [JsonProperty(PropertyName = "startView", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public short StartView { get; set; }
        [JsonProperty(PropertyName = "withInitialDate", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool WithInitialDate { get; set; }
        [JsonProperty(PropertyName = "showTimePanel", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool ShowTimePanel { get; set; }
        /* GrayParrotDateTimePickerOptionsAttribute */

        [JsonProperty(PropertyName = "files", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public string[] Files { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="TemplateOptions"/> class.
        /// </summary>
        public TemplateOptions()
        {
            Value = null;
            FieldGroup = null;
            this.Events = new List<EventCallback>();
            this.Options = new List<object>();
            this.MinView = 0;
        }

        public bool ShouldSerializeMinView()
        {
            return (this.Type != "grayParrotDateTimePicker");
        }

        public bool ShouldSerializeFields()
        {
            // don't serialize the property with name repeatSection...
            return (this.Type != "repeatSection");
        }

        public bool ShouldSerializeRSFields()
        {
            // serialize the property with name repeatSection...
            return (this.Type == "repeatSection");
        }

        public bool ShouldSerializeEvents()
        {
            // don't serialize the property with name Events...
            return (this.Type != "Events");
        }
    }
}
